package com.smasher.widget.biometric

import android.content.Context
import android.util.Log
import androidx.biometric.BiometricManager
import androidx.biometric.BiometricPrompt
import androidx.biometric.BiometricPrompt.PromptInfo
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentActivity

object BiometricUtil {

    private const val TAG = "BiometricUtil"

    /**
     * 返回值见上文的“是否可用的状态码”
     */
    private fun isFingerprintAvailable(context: Context): Int {
        val manager = BiometricManager.from(context)
        return manager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK)
    }

    /**
     * 开始验证
     *
     * @param activity activity
     * @param callBack 验证结果回调
     */
    private fun authenticate(
        activity: FragmentActivity,
        callBack: BiometricPrompt.AuthenticationCallback
    ) {
        val promptInfo = createUi()
        val prompt = BiometricPrompt(activity, ContextCompat.getMainExecutor(activity), callBack)
        prompt.authenticate(promptInfo)
    }

    /**
     * 编辑弹窗
     */
    private fun createUi(): PromptInfo {
        return PromptInfo.Builder()
            .setTitle("指纹验证")
            .setNegativeButtonText("使用密码登录")
            .build()
    }

    @JvmStatic
    fun authenticate(activity: FragmentActivity, callback: AuthenticationCallback) {
        authenticate(activity, object : BiometricPrompt.AuthenticationCallback() {
            /**
             * 验证过程中发生了错误
             * @param errorCode errorCode
             * @param errString errString
             */
            override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
                resolveAuthenticationError(errorCode, errString, callback)
            }

            /**
             * 验证成功
             * @param result An object containing authentication-related data.
             */
            override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
                Log.d(TAG, "验证成功") //该自己处理后续了
                callback.onSuccess()
            }

            /**
             * 验证失败
             */
            override fun onAuthenticationFailed() {
                super.onAuthenticationFailed()
                Log.d(TAG, "验证失败，请重试")
                callback.onFailed("验证失败，请重试")
            }
        })
    }


    private fun resolveAuthenticationError(
        errorCode: Int,
        errString: CharSequence,
        callback: AuthenticationCallback
    ) {
        Log.i(TAG, errString.toString())
        when (errorCode) {
            BiometricPrompt.ERROR_USER_CANCELED -> {
                Log.d(TAG, "取消了指纹识别")
                callback.onMessage("取消了指纹识别")
            }

            BiometricPrompt.ERROR_LOCKOUT -> {
                Log.d(TAG, "失败5次，已锁定，请30秒后在试")
                callback.onError("失败5次，已锁定，请30秒后在试")
            }

            BiometricPrompt.ERROR_LOCKOUT_PERMANENT -> {
                Log.d(TAG, "失败次数太多，指纹验证已锁定，请改用密码方式登录")
                callback.onMessage("失败次数太多，指纹验证已锁定，请改用密码方式登录")
            }

            BiometricPrompt.ERROR_NEGATIVE_BUTTON ->                 //取消按钮
                callback.onNegative()

            BiometricPrompt.ERROR_NO_DEVICE_CREDENTIAL -> {
                Log.d(TAG, "尚未设置指纹密码，请改用密码方式登录")
                callback.onMessage("尚未设置指纹密码，请改用密码方式登录")
            }

            BiometricPrompt.ERROR_NO_SPACE -> {
                Log.d(TAG, "可用空间不足")
                callback.onError("可用空间不足")
            }

            BiometricPrompt.ERROR_TIMEOUT -> {
                Log.d(TAG, "验证超时")
                callback.onError("验证超时")
            }

            BiometricPrompt.ERROR_HW_UNAVAILABLE -> {
                Log.d(TAG, "硬件不可用,请稍后重试")
                callback.onError("验证超时")
            }

            BiometricPrompt.ERROR_UNABLE_TO_PROCESS -> {
                Log.d(TAG, "传感器无法处理当前图像")
                callback.onError("验证超时")
            }

            BiometricPrompt.ERROR_CANCELED -> {
                Log.d(TAG, "传感器不可用，操作已被取消")
                callback.onError("验证超时")
            }

            BiometricPrompt.ERROR_VENDOR -> {
                Log.d(TAG, "特定的错误，操作失败")
                callback.onError("验证超时")
            }

            BiometricPrompt.ERROR_NO_BIOMETRICS -> {
                Log.d(TAG, "用户未注册生物识别")
                callback.onError("验证超时")
            }

            BiometricPrompt.ERROR_HW_NOT_PRESENT -> {
                Log.d(TAG, "设备没有所需的身份验证硬件")
                callback.onError("验证超时")
            }

            else -> {}
        }
    }


    @JvmStatic
    fun startBiometric(activity: Context, callback: AuthenticationStatusCallback) {
        val available = isFingerprintAvailable(activity)
        when (available) {
            BiometricManager.BIOMETRIC_SUCCESS -> {
                callback.onAuthenticationStable()
            }

            BiometricManager.BIOMETRIC_STATUS_UNKNOWN -> {
                Log.d(TAG, "未知错误，请重试")
                callback.onAuthenticationError("未知错误，请重试")
            }

            BiometricManager.BIOMETRIC_ERROR_UNSUPPORTED -> {
                Log.d(TAG, "当前手机的Android版本不支持")
                callback.onAuthenticationUnsupported("当前手机的Android版本不支持")
            }

            BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE -> {
                Log.d(TAG, "当前指纹传感器不可用，清稍后再试")
                callback.onAuthenticationUnsupported("当前指纹传感器不可用，清稍后再试")
            }

            BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED -> {
                Log.d(TAG, "当前设备未录入指纹，请先录入指纹")
                callback.onAuthenticationNoneEnrolled("当前设备未录入指纹，请先录入指纹")
            }

            BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE -> {
                Log.d(TAG, "未检测到手机指纹传感器")
                callback.onAuthenticationUnsupported("未检测到手机指纹传感器")
            }

            BiometricManager.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED -> {
                Log.d(TAG, "传感器存在已知的漏洞，在更新修复漏洞前，传感器不可用")
                callback.onAuthenticationError("传感器存在已知的漏洞，在更新修复漏洞前，传感器不可用")
            }

            else -> {}
        }
    }

}
